<?php
/***********************************************************************
 * @package    IvanEngine
 * @subpackage Core
 * @author     Ivan <ivanzx@msn.com>
 * @created    2010-05-22
 ***********************************************************************/
if(defined("IVANENGINE_CORE_STL_ARRAY"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_STL_ARRAY", true);

require_once (dirname(__FILE__).'/../Base.php');
require_once (dirname(__FILE__).'/Iterator.php');

class CArray extends CBase implements Iterator//, Serializable
{
	protected $m_array     = array();
	
    public function __construct(array & $array = null) 
    {
        parent::__construct();
        if( $array != null ){
            $this->m_array  = $array;
        }
    }

    public function __destruct()
    {
        unset($this->m_array);
        parent::__destruct();
    }
    
    public function Append(CArray & $array)
    {
        if( $array ){
            $this->m_array = array_merge($this->m_array, $array->GetArray());
        }
    }
    
    public function AppendArray(array & $array)
    {
        if( $array ){
            $this->m_array = array_merge($this->m_array, $array);
        }
    }
    
    public function Add($val)
    {
    	array_push($this->m_array, $val);
    }
    
    public function Insert($where, $val)
    {
        $this->_VerifIndex($where);
        
    	$newArray  = array();
        for ($i = 0; $i < $where; $i++)
        {
            array_push($newArray, $this->m_array[$i]);
        }
        array_push($newArray, $val);
        
        for ($i = $where; $i < $this->Size(); $i++)
        {
            array_push($newArray, $this->m_array[$i]);
        }
        
        $this->m_array  = $newArray;
    }
    
    protected function _VerifIndex($index)
    {
        if( !is_int($index) ){
            throw new CExceptionInvalidArgument(
                'the parameter must be a interget value.');
        }
    }
    
    public function RemoveByKey($where)
    {
        $this->_VerifIndex($where);
        
        if( $this->key() == $where ){
            $this->rewind();
        }
        unset($this->m_array[$where]);
    }
    
    public function Remove($where)
    {
        $pos = array_search($where, $this->m_array);
        if( $pos !== FALSE ){
            $this->RemoveByKey($pos);
        }
    }
    
    public function Erase(CIterator $iter)
    {
        $this->Remove($iter->Pos());
    }
    
    public function Has($value)
    {
    	if( $this->Find($value) == false )
    	{
    		return false;
    	}
    	return true;
    }
    
    public function Set($where, $val)
    {
        if( $this->Get($where) === null )
            return;
        $this->m_array[$where]  = $val;
    }
    
    public function & Get($where)
    {
    	if($where < 0 || $where > $this->Size() )
            return null;
        $val = $this->m_array[$where];
        return $val;
    }
    
    public function & Values()
    {
    	return $this->m_array;
    }
    
    public function & GetArray()
    {
        return $this->m_array;
    }

    public function Find($value)
    {
        return array_search($value, $this->m_array) !== FALSE;
    }
    
    public function Begin()
    {
    	return new CIterator($this, 0);
    }
    
    public function End()
    {
    	return new CIterator($this, $this->Size());
    }
    
    public function Size()
    {
    	return count($this->m_array);
    }
    
    public function IsEmpty()
    {
        return $this->Size() == 0;
    }
    
    public function Reverse()
    {
        array_reverse($this->m_array);
    }
    
    public function Clear()
    {
        foreach($this->m_array as $key => $val){
            unset($this->m_array[$key]);
        }
    }
    
    public function rewind() 
    { 
        reset($this->m_array);
    }
    
    public function current() 
    { 
        return current($this->m_array); 
    }
    
    public function key() 
    { 
        return key($this->m_array); 
    }
    
    public function next() 
    { 
        return next($this->m_array); 
    }
    
    public function valid() 
    { 
        return ($this->current() !== FALSE);
    }
}

?>
